package com.frank.work;

import com.alibaba.excel.util.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * @author 小石潭记
 * @date 2021/12/21 8:53
 * @Description: 流水线管理
 */
@Service
public class PipelineManager {

    @Autowired
    private ApplicationContextProvider applicationContextProvider;

    private Map<String, PipelineNode> pipelineTaskRootNodeHashMap = new HashMap<>();

    @Autowired
    private TaskGroupConfigRepository taskGroupConfigRepository;

    @PostConstruct
    public void init() {
        List<TaskGroupConfigEntity> taskGroupConfigEntityList = taskGroupConfigRepository.findAll();
        // 查询数据库配置的任务
        initPipelineTask(taskGroupConfigEntityList);
    }

    /*private void initPipelineTask(List<TaskGroupConfigEntity> entities) {
        Map<String, Map<String, PipelineNode>> pipelineCacheTaskHashMap = new HashMap<>();
        //将数据库对象根据group去重，转换为group列表
        List<String> groupKeys = entities.stream().filter(distinctByKey(item -> item.getTaskGroup()))
                .map(item -> item.getTaskGroup()).collect(Collectors.toList());
        // key是任务名
        Map<String, PipelineNode> pipelineTasks = new HashMap<>();
        //根据groupName初始化构建pipelineTaskHashMap
        for (String groupKey : groupKeys) {
            for (TaskGroupConfigEntity entity : entities) {
                if (groupKey.equals(entity.getTaskGroup())) {
                    PipelineNode pipelineNode = new PipelineNode();
                    pipelineNode.setNodeTask((AbstractPipelineNodeTask) applicationContextProvider.getBeanByName(entity.getTaskName()));
                    pipelineNode.setTaskName(entity.getTaskName());
                    pipelineNode.setTaskGroup(entity.getTaskGroup());
                    List<String> subTaskName = entity.getSubTaskName();
                    // 如果子节点数大于1 则多个节点
                    pipelineNode.setManyNodeFlag(subTaskName.size() > 1);
                    pipelineTasks.put(entity.getTaskName(), pipelineNode);

                    for (String taskName : subTaskName) {
                        if (pipelineTasks.get(taskName) == null) {
                            PipelineNode subPipelineNode = new PipelineNode();
                            subPipelineNode.setNodeTask((AbstractPipelineNodeTask) applicationContextProvider.getBeanByName(entity.getTaskName()));
                            subPipelineNode.setTaskName(taskName);
                            subPipelineNode.setTaskGroup(entity.getTaskGroup());
                            subPipelineNode.setManyNodeFlag(false);
                            pipelineTasks.put(taskName, subPipelineNode);
                        }
                    }
                }
            }
            pipelineCacheTaskHashMap.put(groupKey, pipelineTasks);
        }

        //填充childTasks
        entities.forEach(item -> {
            if (CollectionUtils.isEmpty(item.getSubTaskName())) {
                return;
            }
            //获取初始化的根节点
            PipelineNode pipelineNode = pipelineCacheTaskHashMap.get(item.getTaskGroup()).get(item.getTaskName());
            List<PipelineNode> pipelineSubTasks = new ArrayList<>(item.getSubTaskName().size());
            List<String> subTaskNameList = item.getSubTaskName();
            for (String taskName : subTaskNameList) {
                pipelineSubTasks.add(pipelineCacheTaskHashMap.get(item.getTaskGroup()).get(taskName));
            }
            pipelineNode.setChildNodes(pipelineSubTasks);
            //如果是根节点就加入pipelineTaskHashMap
            if (item.getRootFlag()) {
                pipelineTaskRootNodeHashMap.put(item.getTaskGroup(), pipelineNode);
            }
        });
    }*/

    private void initPipelineTask(List<TaskGroupConfigEntity> entities) {
        Map<String, Map<String, PipelineNode>> pipelineCacheTaskHashMap = new HashMap<>();

        //将数据库对象根据group去重，转换为group列表
        List<String> groupKeys = entities.stream().filter(distinctByKey(item -> item.getTaskGroup()))
                .map(item -> item.getTaskGroup()).collect(Collectors.toList());

        //根据groupName初始化构建pipelineTaskHashMap
        groupKeys.forEach(
                groupKey -> {
                    Map<String, PipelineNode> pipelineTasks = entities.stream().filter(item -> {
                        return groupKey.equals(item.getTaskGroup());
                    }).map(item -> {
                        PipelineNode pipelineNode = new PipelineNode();
                        pipelineNode.setNodeTask((AbstractPipelineNodeTask) applicationContextProvider.getBeanByName(item.getTaskName()));
                        pipelineNode.setTaskName(item.getTaskName());
                        pipelineNode.setTaskGroup(item.getTaskGroup());
                        return pipelineNode;
                    }).collect(Collectors.toMap(PipelineNode::getTaskName, pipelineNode -> pipelineNode));

                    pipelineCacheTaskHashMap.put(groupKey, pipelineTasks);
                }
        );

        //填充childTasks
        entities.forEach(item -> {
            if (CollectionUtils.isEmpty(item.getSubTaskName())) {
                return;
            }
            //获取初始化的根节点
            PipelineNode pipelineNode = pipelineCacheTaskHashMap.get(item.getTaskGroup()).get(item.getTaskName());

            List<PipelineNode> pipelineSubTasks = new ArrayList<>(item.getSubTaskName().size());

            item.getSubTaskName().forEach(taskName -> {
                pipelineSubTasks.add(pipelineCacheTaskHashMap.get(item.getTaskGroup()).get(taskName));
            });

            pipelineNode.setChildNodes(pipelineSubTasks);

            //如果是根节点就加入pipelineTaskHashMap
            if (item.getRootFlag()) {
                pipelineTaskRootNodeHashMap.put(item.getTaskGroup(), pipelineNode);
            }
        });
    }

    /**
     * @param groupKey
     * @return
     */
    public PipelineNode getRootPipelineTaskByGroupKey(String groupKey) {
        return pipelineTaskRootNodeHashMap.get(groupKey);
    }

    /**
     * @return
     */
    public Map<String, PipelineNode> getRootPipelineTasks() {
        return pipelineTaskRootNodeHashMap;
    }

    /**
     * 将数据库对象根据group去重，转换为group列表
     *
     * @param keyExtractor
     * @param <T>
     * @return
     */
    private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Map<Object, Boolean> seen = new HashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;

    }

}
